/*
 * Copyright (c) 2017. All  rights reserved.
 * 项目名：microservice-base
 * 文件名：TokenAuthentication.java
 * Date  ：17-11-29 上午10:25
 * Author：abin
 *
 */

package com.microservice.base.common;

import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2017/11/14.
 */
public class TokenAuthentication {
    static final long EXPIRATIONTIME = 432_000_000; // 5天
    static final String SECRET = "P@ssw02d"; // JWT密码
    static final String TOKEN_PREFIX = "Bearer"; // Token前缀
    public static final String HEADER_STRING = "Authorization";// 存放Token的Header Key
    @Autowired
    RestTemplate restTemplate;
    @Value("${innerUrl.BASEPATH}" + "${innerUrl.CHECKOUTTOCKEN}")
    private String CHECKOUTTOCKEN;

    Logger logger = Logger.getLogger(this.getClass());


    // JWT验证方法
    public Authentication authToken(HttpServletRequest request, HttpServletResponse httpServletResponse) {
        // 从Header中拿到token
        String token = request.getHeader(HEADER_STRING);
        //tokenId
        String tokenId = null;
        if (token != null) {
            // 解析 Token
            Claims claims = Jwts.parser()
                    // 验签
                    .setSigningKey(SECRET)
                    // 去掉 Bearer
                    .parseClaimsJws(token.replace(TOKEN_PREFIX, "")).getBody();
            List<GrantedAuthority> user = AuthorityUtils
                    .commaSeparatedStringToAuthorityList((String) claims.get("User"));
            //获得url
            List<GrantedAuthority> authorities = AuthorityUtils
                    .commaSeparatedStringToAuthorityList((String) claims.get("tokenId"));
            boolean ifPermission = getPermission(authorities, request);
            tokenId = String.valueOf(authorities.get(0));
            String JWT = Jwts.builder()
                    // 保存权限（角色）
                    .claim("User", (String) claims.get("User"))
                    .claim("tokenId", tokenId)
                    // 有效期设置
                    .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
                    // 签名设置
                    .signWith(SignatureAlgorithm.HS512, SECRET).compact();
            httpServletResponse.setHeader(HEADER_STRING, JWT);
            if (ifPermission) {
                // 将 JWT 写入 body
                return new UsernamePasswordAuthenticationToken(user.get(0) + "," + user.get(2) + "," + user.get(3), user.get(1));
            } else {
                return null;
            }
        }
        return null;
    }


    /**
     * 校验url
     *
     * @param authorities
     * @param request
     * @return
     */
    public Boolean getPermission(List<GrantedAuthority> authorities, HttpServletRequest request) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("tockenId", authorities.get(0));
        jsonObject.put("requestPath", request.getServletPath());
        JSONObject json = restTemplate.postForEntity(CHECKOUTTOCKEN, jsonObject, JSONObject.class).getBody();
        boolean ret = json.getBoolean("ret");
        return ret;
    }
}
